#include <iostream>
using namespace std;

/*
    多态：同一个方法在父类和子类中具有不同的表示形式，传递不同子类可以使用不同子类的同名方法（接口统一，实现不同）
        父类的指针或者父类的引用作为函数的形参具有兼容性，可以兼容父类以及父类派生出来的子类对象
    虚函数： virtual 返回值 函数名（形参）
        作用：允许在运行时根据对象的实际类型来调用相应的函数
        原理：
            1.一个类定义了虚函数，这个类地址空间会多一个指针
            2。该指针用来指向虚函数表（虚表）首地址
                虚函数表：用于存放当前类的所有虚函数的首地址的数据结构
                    如果子类没用重写父类的方法，那么存放的是父类的方法；
                    如果子类重写父类方法，那么存放的是子类重写后的方法 
            3.父类定义虚函数，子类中于父类同名的函数默认也是虚函数
                父类eat()定义成虚函数，子类中的eat()默认也是虚函数
        override：重写  
            语法：返回值类型 函数名（形参） override
            作用：明确告诉编译器，这个函数是重写父类的

*/

class Animal
{
public:
    virtual void eat()
    {
        cout << "Animal吃" << endl;
    }
};

class Cat : public Animal
{
public:
    void eat() 
    {
        cout << "猫吃鱼" << endl;
    }
};
class Dog : public Animal
{
public:
    void eat()
    {
        cout << "狗吃骨头" << endl;
    }
};
class Sheep : public Animal
{
public:
    void eat()
    {
        cout << "羊吃草" << endl;
    }
};
class Pig : public Animal
{
public:
    void eat()
    {
        cout << "猪吃白菜" << endl;
    }
};

class HaoCat:public Cat
{
public:
    void eat()
    {
        cout << "好猫吃鱼" << endl;
    }
};
// 展示动物吃什么
void showAnimalEat(Animal &other)
{
    other.eat();
}

int main()
{
    Animal animal;
    Cat cat;
    Dog dog;
    Sheep sheep;
    Pig pig;
    HaoCat haoCat;
    showAnimalEat(animal);
    showAnimalEat(cat);
    showAnimalEat(dog);
    showAnimalEat(sheep);
    showAnimalEat(pig);
    showAnimalEat(haoCat);
    return 0;
}